﻿#include "LowEnergyInfoModel.h"
#include <QDebug>


LowEnergyInfoModel *LowEnergyInfoModel::Singleton()
{
    static LowEnergyInfoModel * singleton = new LowEnergyInfoModel();
    return singleton;
}

LowEnergyInfoModel::LowEnergyInfoModel(QObject *parent ) : QAbstractListModel(parent)
{
#if 0
    addService("Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");
    addCharacteristic("CH01", "{00UUID01-0000-1000-8000-00805f9b34fb}", 1, "值", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");
    addDescriptor("descriptor01", "{Descriptor01-0000-1000-8000-00805f9b34fb}", "值", "CH01", "{00UUID01-0000-1000-8000-00805f9b34fb}", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");

    addCharacteristic("CH02", "{00UUID02-0000-1000-8000-00805f9b34fb}", 1, "值", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");
    addDescriptor("descriptor01", "{Descriptor01-0000-1000-8000-00805f9b34fb}", "值", "CH02", "{00UUID02-0000-1000-8000-00805f9b34fb}", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");

    addCharacteristic("CH03", "{00UUID03-0000-1000-8000-00805f9b34fb}", 1, "值", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");
    addDescriptor("descriptor01", "{Descriptor01-0000-1000-8000-00805f9b34fb}", "值", "CH03", "{00UUID03-0000-1000-8000-00805f9b34fb}", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");

    addCharacteristic("CH03", "{00UUID04-0000-1000-8000-00805f9b34fb}", 1, "值", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");
    addCharacteristic("CH03", "{00UUID05-0000-1000-8000-00805f9b34fb}", 1, "值", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");
    addCharacteristic("CH03", "{00UUID06-0000-1000-8000-00805f9b34fb}", 1, "值", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");
    addCharacteristic("CH03", "{00UUID07-0000-1000-8000-00805f9b34fb}", 1, "值", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");
    addCharacteristic("CH03", "{00UUID08-0000-1000-8000-00805f9b34fb}", 1, "值", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");
    addCharacteristic("CH03", "{00UUID09-0000-1000-8000-00805f9b34fb}", 1, "值", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");
    addCharacteristic("CH03", "{00UUID10-0000-1000-8000-00805f9b34fb}", 1, "值", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");
    addCharacteristic("CH03", "{00UUID11-0000-1000-8000-00805f9b34fb}", 1, "值", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");
    addCharacteristic("CH03", "{00UUID12-0000-1000-8000-00805f9b34fb}", 1, "值", "Generic Access", "{00001800-0000-1000-8000-00805f9b34fb}");


    addService("Generic Attribute", "{00001801-0000-1000-8000-00805f9b34fb}");
#endif
}

int LowEnergyInfoModel::rowCount(const QModelIndex &) const
{
    return mBluetoothInfoList.count();
}

QVariant LowEnergyInfoModel::data(const QModelIndex &index, int role) const
{
    if (index.row() < rowCount())
    {
        switch (role) {
        case serviceNameRole: return mBluetoothInfoList.at(index.row()).serviceName;
        case rowTypeRole: return mBluetoothInfoList.at(index.row()).rowType;
        case serviceUuidRole: return mBluetoothInfoList.at(index.row()).serviceUuid;
        case characteristicNameRole: return mBluetoothInfoList.at(index.row()).characteristicName;
        case characteristicUuidRole: return mBluetoothInfoList.at(index.row()).characteristicUuid;
        case characteristicPropertyRole: return (int)mBluetoothInfoList.at(index.row()).characteristicProperty;
        case descriptorNameRole: return mBluetoothInfoList.at(index.row()).descriptorName;
        case descriptorUuidRole: return mBluetoothInfoList.at(index.row()).descriptorUuid;
        case chDescValueRole: return mBluetoothInfoList.at(index.row()).chDescValue;
        case childItemCountRole: return mBluetoothInfoList.at(index.row()).childItemCount;

        default: return QVariant();
        }
    }
    return QVariant();
}

QHash<int, QByteArray> LowEnergyInfoModel::roleNames() const
{
    static const QHash<int, QByteArray> roles {
        { serviceNameRole, "serviceName" },
        { rowTypeRole, "rowType" },
        { serviceUuidRole, "serviceUuid" },
        { characteristicNameRole, "characteristicName" },
        { characteristicUuidRole, "characteristicUuid" },
        { characteristicPropertyRole, "characteristicProperty" },
        { descriptorNameRole, "descriptorName" },
        { descriptorUuidRole, "descriptorUuid" },
        { chDescValueRole, "chDescValue" },
        { childItemCountRole, "childItemCount" },
    };
    return roles;
}


QVariantMap LowEnergyInfoModel::get(int row) const
{
    const RowData rowData = mBluetoothInfoList.value(row);
    return { {"serviceName", rowData.serviceName}
        , {"rowType", rowData.rowType}
        , {"serviceUuid", rowData.serviceUuid}
        , {"characteristicName", rowData.characteristicName}
        , {"characteristicUuid", rowData.characteristicUuid}
        , {"characteristicProperty", rowData.characteristicProperty}
        , {"descriptorName", rowData.descriptorName}
        , {"descriptorUuid", rowData.descriptorUuid}
        , {"chDescValue", rowData.chDescValue }
        , {"childItemCount", rowData.childItemCount }
    };
}

void LowEnergyInfoModel::addService(const QString& serviceName, const QString& serviceUuid)
{
    for (int row = 0; row < mBluetoothInfoList.count(); ++row)
    {
        if(EnumRowType_Service == mBluetoothInfoList.at(row).rowType
                //&& serviceName == mBluetoothInfoList.at(row).serviceName
                && serviceUuid == mBluetoothInfoList.at(row).serviceUuid
                )
        {
            if(serviceName != mBluetoothInfoList.at(row).serviceName)
            {
                mBluetoothInfoList[row].serviceName = serviceName;
                dataChanged(index(row, 0), index(row, 0), {serviceNameRole});
                qDebug() << "row:" << row << "serviceName changed:" << serviceName;
            }
            return ;
        }
    }

    int row = 0;
    for (; row < mBluetoothInfoList.size(); ++row)
    {
        if(mBluetoothInfoList.at(row).rowType < EnumRowType_Service)
        {// 已经是下一个组
            break;
        }
        if(mBluetoothInfoList.at(row).rowType > EnumRowType_Service)
        {// 更内部的分组
            continue;
        }
        if(serviceUuid > mBluetoothInfoList.at(row).serviceUuid)
        {
            continue;
        }
        else
        {
            break;
        }
    }
    beginInsertRows(QModelIndex(), row, row);
    RowData rowData;
    rowData.rowType = EnumRowType_Service;
    rowData.serviceName = serviceName;
    rowData.serviceUuid = serviceUuid;
    mBluetoothInfoList.insert(row, rowData);
    endInsertRows();
}

void LowEnergyInfoModel::addCharacteristic(const QString &characteristicName, const QString &characteristicUuid, int property, QString value, const QString& serviceName, const QString& serviceUuid)
{
    for (int row = 0; row < mBluetoothInfoList.count(); ++row)
    {
        if(EnumRowType_Characteristic == mBluetoothInfoList.at(row).rowType
                //&& characteristicName == mBluetoothInfoList.at(row).characteristicName
                && characteristicUuid == mBluetoothInfoList.at(row).characteristicUuid
                && serviceUuid == mBluetoothInfoList.at(row).serviceUuid
                )
        {
            if(characteristicName != mBluetoothInfoList.at(row).characteristicName)
            {
                mBluetoothInfoList[row].characteristicName = characteristicName;
                mBluetoothInfoList[row].characteristicProperty = property;
                dataChanged(index(row, 0), index(row, 0), {characteristicNameRole, characteristicPropertyRole});
                qDebug() << "row:" << row << "characteristicName changed:" << characteristicName;
            }
            return ;
        }
    }
    // 查找属于的服务
    int serviceIndex = -1;
    for (int row = 0; row < mBluetoothInfoList.count(); ++row)
    {
        if(EnumRowType_Service == mBluetoothInfoList.at(row).rowType
                && serviceUuid == mBluetoothInfoList.at(row).serviceUuid
                )
        {
            serviceIndex = row;
            break;
        }
    }
    if(-1 == serviceIndex)
    {
        qDebug() << "find sevice row Failed";
        return ;
    }

    int row = serviceIndex + 1;
    for (; row < mBluetoothInfoList.size(); ++row)
    {
        if(mBluetoothInfoList.at(row).rowType < EnumRowType_Characteristic)
        {// 已经是下一个组
            break;
        }
        if(mBluetoothInfoList.at(row).rowType > EnumRowType_Characteristic)
        {// 更内部的分组
            continue;
        }
        if(characteristicUuid > mBluetoothInfoList.at(row).characteristicUuid)
        {
            continue;
        }
        else
        {
            break;
        }
    }
    beginInsertRows(QModelIndex(), row, row);
    RowData rowData;
    rowData.rowType = EnumRowType_Characteristic;
    rowData.serviceName = serviceName;
    rowData.serviceUuid = serviceUuid;
    rowData.characteristicName = characteristicName;
    rowData.characteristicUuid = characteristicUuid;
    rowData.characteristicProperty = property;
    rowData.chDescValue = value;
    mBluetoothInfoList.insert(row, rowData);
    endInsertRows();
    // 子项数加1
    mBluetoothInfoList[serviceIndex].childItemCount++;
    dataChanged(index(serviceIndex, 0), index(serviceIndex, 0), {childItemCountRole});

}

void LowEnergyInfoModel::addDescriptor(const QString &descriptorName, const QString &descriptorUuid, QString value, const QString& characteristicName, const QString& characteristicUuid, const QString& serviceName, const QString& serviceUuid)
{
    /*
    qDebug() << "addDescriptor:" << descriptorName
             << " " << descriptorUuid
             << " " << characteristicName
             << " " << characteristicUuid
             << " " << serviceName
             << " " << serviceUuid;
    */
    for (int row = 0; row < mBluetoothInfoList.count(); ++row)
    {
        if(EnumRowType_Descriptor == mBluetoothInfoList.at(row).rowType
                //&& descriptorName == mBluetoothInfoList.at(row).descriptorName
                && descriptorUuid == mBluetoothInfoList.at(row).descriptorUuid
                && characteristicUuid == mBluetoothInfoList.at(row).characteristicUuid
                && serviceUuid == mBluetoothInfoList.at(row).serviceUuid
                )
        {
            if(descriptorName != mBluetoothInfoList.at(row).descriptorName)
            {
                mBluetoothInfoList[row].descriptorName = descriptorName;
                dataChanged(index(row, 0), index(row, 0), {descriptorNameRole});
                qDebug() << "row:" << row << "descriptorName changed:" << descriptorName;
            }
            return ;
        }
    }
    // 查找属于的characteristic
    int characteristicIndex = -1;
    for (int row = 0; row < mBluetoothInfoList.count(); ++row)
    {
        if(EnumRowType_Characteristic == mBluetoothInfoList.at(row).rowType
                && characteristicUuid == mBluetoothInfoList.at(row).characteristicUuid
                )
        {
            characteristicIndex = row;
            break;
        }
    }
    if(-1 == characteristicIndex)
    {
        qDebug() << "find characteristic row Failed";
        return ;
    }

    int row = characteristicIndex + 1;
    for (; row < mBluetoothInfoList.size(); ++row)
    {
        if(mBluetoothInfoList.at(row).rowType < EnumRowType_Descriptor)
        {// 已经是下一个组
            break;
        }
        if(mBluetoothInfoList.at(row).rowType > EnumRowType_Descriptor)
        {// 更内部的分组
            continue;
        }

        if(descriptorUuid > mBluetoothInfoList.at(row).descriptorUuid)
        {
            continue;
        }
        else
        {
            break;
        }
    }
    beginInsertRows(QModelIndex(), row, row);
    RowData rowData;
    rowData.rowType = EnumRowType_Descriptor;
    rowData.serviceName = serviceName;
    rowData.serviceUuid = serviceUuid;
    rowData.characteristicName = characteristicName;
    rowData.characteristicUuid = characteristicUuid;
    rowData.descriptorName = descriptorName;
    rowData.descriptorUuid = descriptorUuid;
    rowData.chDescValue = value;
    mBluetoothInfoList.insert(row, rowData);
    endInsertRows();
    //qDebug() << "addDescriptor:" << row;
    // 子项数加1
    mBluetoothInfoList[characteristicIndex].childItemCount++;
    dataChanged(index(characteristicIndex, 0), index(characteristicIndex, 0), {childItemCountRole});
}

void LowEnergyInfoModel::updateCharacteristicValue(const QString &characteristicUuid, const QString& serviceUuid, QString value)
{
    for (int row = 0; row < mBluetoothInfoList.count(); ++row)
    {
        if(EnumRowType_Characteristic == mBluetoothInfoList.at(row).rowType
                && characteristicUuid == mBluetoothInfoList.at(row).characteristicUuid
                && serviceUuid == mBluetoothInfoList.at(row).serviceUuid
                )
        {
            if(mBluetoothInfoList[row].chDescValue != value)
            {
                mBluetoothInfoList[row].chDescValue = value;
                dataChanged(index(row, 0), index(row, 0), {chDescValueRole});
            }
            return ;
        }
    }
}

void LowEnergyInfoModel::updateDescriptorValue(const QString& descriptorUuid, const QString& characteristicUuid, const QString& serviceUuid, QString value)
{
    //qDebug() << "updateDescriptorValue:" << descriptorUuid << "  " << value;
    for (int row = 0; row < mBluetoothInfoList.count(); ++row)
    {
        if(EnumRowType_Descriptor == mBluetoothInfoList.at(row).rowType
                && descriptorUuid == mBluetoothInfoList.at(row).descriptorUuid
                && characteristicUuid == mBluetoothInfoList.at(row).characteristicUuid
                && serviceUuid == mBluetoothInfoList.at(row).serviceUuid
                )
        {
            if(mBluetoothInfoList[row].chDescValue != value)
            {
                mBluetoothInfoList[row].chDescValue = value;
                dataChanged(index(row, 0), index(row, 0), {chDescValueRole});
                //qDebug() << "updateDescriptorValue:" << descriptorUuid << "  " << value;
            }
            return ;
        }
    }
}

void LowEnergyInfoModel::remove(int row)
{
    if (row < 0 || row >= mBluetoothInfoList.count())
    {
        return;
    }
    EnumRowType rowType = mBluetoothInfoList.at(row).rowType;
    beginRemoveRows(QModelIndex(), row, row);
    mBluetoothInfoList.removeAt(row);
    endRemoveRows();

    //
    if(rowType == LowEnergyInfoModel::EnumRowType_Characteristic
            || rowType == LowEnergyInfoModel::EnumRowType_Descriptor)
    {
        for(int i = row - 1; i >= 0; --i)
        {
            if(rowType - mBluetoothInfoList.at(i).rowType == 1)
            {
                // 子项数-1
                if(mBluetoothInfoList[i].childItemCount > 0)
                {
                    mBluetoothInfoList[i].childItemCount--;
                    dataChanged(index(i, 0), index(i, 0), {childItemCountRole});
                }
                break;
            }
        }
    }
}

void LowEnergyInfoModel::clear()
{
    int count = mBluetoothInfoList.count();
    if(count > 0)
    {
        beginRemoveRows(QModelIndex(), 0, count-1);
        mBluetoothInfoList.clear();
        endRemoveRows();
    }
}

